﻿using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows;
using Rectangle=System.Drawing.Rectangle;

namespace VideoRenderExample
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        /* For GDI Test */
        private Bitmap m_gdiBitmap = new Bitmap(320, 240, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        private Graphics m_gdiGraphics;
        private int m_gdiAnimCounter = 0;

        /* For MJPEG Test */
        private byte[] jpeg1;
        private byte[] jpeg2;

        /* Misc ish... */
        private bool m_endTest = false;
        private int m_frameCount = 0;
        private ThreadStart m_threadStart;

        private CaptureDevice m_capDev = new CaptureDevice();

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            videoRenderer.RendererInitialized += RendererInitialized;
           
            GDITest.Click += GDITest_Click;
            MJPGTest.Click += MJPGTest_Click;
            WebcamTest.Click += WebcamTest_Click;

            m_capDev.OnNewSample += new CaptureDevice.NewSampleDelegate(m_capDev_OnNewSample);
        }

        private void m_capDev_OnNewSample(System.IntPtr pBuffer, int cSize)
        {
            videoRenderer.WriteSample(pBuffer, cSize, true);
        }

        private void WebcamTest_Click(object sender, RoutedEventArgs e)
        {
            m_endTest = true;
            m_threadStart = RunWebCam;
            videoRenderer.TearDown();
            videoRenderer.InitializeVideo(640, 480, 24);
        }

        private void MJPGTest_Click(object sender, RoutedEventArgs e)
        {
            m_endTest = true;
            m_threadStart = MJPEGLoop;
            videoRenderer.TearDown();
            videoRenderer.InitializeVideo(640, 480, 24, "MJPG");
        }

        private void GDITest_Click(object sender, RoutedEventArgs e)
        {
            m_endTest = true;
            m_threadStart = GDIGraphicsLoop;
            videoRenderer.TearDown();
            videoRenderer.InitializeVideo(m_gdiBitmap.Width, -m_gdiBitmap.Height, 24);
        }

        private void RunWebCam()
        {
            Thread t = new Thread((ThreadStart)delegate
            {
                m_capDev.Run(30, 640, 480);
            });

            t.Start();
        }

        private void MJPEGLoop()
        {
            FileStream fs;

            fs = File.Open(@"untitled.jpg", FileMode.Open, FileAccess.ReadWrite);
            jpeg1 = new byte[fs.Length];

            using (fs)
            {
                fs.Read(jpeg1, 0, (int)fs.Length);
            }

            fs = File.Open(@"untitled2.jpg", FileMode.Open, FileAccess.ReadWrite);
            jpeg2 = new byte[fs.Length];

            using (fs)
            {
                fs.Read(jpeg2, 0, (int)fs.Length);
            }

            while (!m_endTest)
            {
                m_frameCount++;

                if (m_frameCount % 2 == 0)
                {
                    videoRenderer.WriteSample(jpeg1, true);
                }
                else
                {
                    videoRenderer.WriteSample(jpeg2, true);
                }
                
                Thread.Sleep(33);
            }
        }

        private void GDIGraphicsLoop()
        {
            if (m_gdiGraphics == null)
                m_gdiGraphics = Graphics.FromImage(m_gdiBitmap);

            Rectangle rect = new Rectangle(0, 0, m_gdiBitmap.Width, m_gdiBitmap.Height);

            while (!m_endTest)
            {
                m_frameCount++;

                m_gdiAnimCounter += 20;

                if (m_gdiAnimCounter > rect.Width)
                    m_gdiAnimCounter = 0;

                m_gdiGraphics.FillRectangle(new SolidBrush(Color.Blue), rect);

                m_gdiGraphics.FillRectangle(new SolidBrush(Color.Orange), new Rectangle(m_gdiAnimCounter * 2, 0, 20, rect.Height));

                m_gdiGraphics.FillEllipse(new SolidBrush(Color.Red),
                              new Rectangle(m_gdiAnimCounter, rect.Height / 2, 100, 100));
                
                m_gdiGraphics.FillEllipse(new SolidBrush(Color.White),
                                new Rectangle(m_gdiAnimCounter, rect.Height / 2, 80, 80));


                m_gdiGraphics.FillEllipse(new SolidBrush(Color.Red),
                               new Rectangle(0, m_gdiAnimCounter, 100, 100));

                m_gdiGraphics.FillEllipse(new SolidBrush(Color.White),
                                new Rectangle(0, m_gdiAnimCounter, 80, 80));

                m_gdiGraphics.DrawString(m_frameCount.ToString(), new Font("Verdana", 12), new SolidBrush(System.Drawing.Color.Black),
                             new PointF(20, 20)); 

                videoRenderer.WriteSample(m_gdiBitmap, rect);

                /* Throttle FPS */
                Thread.Sleep(33);
            }

            videoRenderer.TearDown();
        }

        private void RendererInitialized()
        {
            Debug.WriteLine("RendererInitialized");
            StartTest();
        }

        private void StartTest()
        {
            m_endTest = false;

            Thread t = new Thread(m_threadStart);
            t.IsBackground = true;
            t.Name = "Test Thread";
            t.Start();
        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            videoRenderer.TearDown();
        }
    }
}
